package com.songlanyun.modules.marketing.seckill.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.songlanyun.common.utils.PageUtils;
import com.songlanyun.modules.goods.model.vo.SkuComItemVo;
import com.songlanyun.modules.marketing.groupbuy.entity.GroupBuyTeam;
import com.songlanyun.modules.marketing.seckill.entity.SeckillActivityGoods;
import com.songlanyun.modules.marketing.seckill.entity.SeckillGoodsSku;
import com.songlanyun.modules.marketing.seckill.model.dto.SeckillActivityGoodsDTO;
import com.songlanyun.modules.marketing.seckill.model.vo.SeckillActivityAppVO;
import com.songlanyun.modules.marketing.seckill.model.vo.SeckillActivityGoodsVO;
import com.songlanyun.modules.marketing.seckill.model.vo.SeckillActivityVO;
import com.songlanyun.modules.order.entity.Order;
import org.redisson.api.RSemaphore;


import java.util.List;
import java.util.Map;

/**
 * 秒杀活动商品表
 *
 * @author Mark
 * @email sunlightcs@gmail.com
 * @date 2020-11-23 17:30:11
 */
public interface SeckillActivityGoodsService extends IService<SeckillActivityGoods> {

    PageUtils goodsPage(Map<String, Object> params);

    void saveGoods(SeckillActivityGoodsDTO dto);

    SeckillActivityGoods getByGoodsIdAndSeckillId(Long goodsId, Long seckillId);

    SeckillActivityGoodsVO getSeckillGoodsById(Long id, Boolean isThrow);

    SeckillActivityGoods loadActivityGoodsById(Long id, Boolean tw);

    void deleteById(Long id);

    List<SeckillActivityGoods> getBySeckillId(Long seckillId);

    SeckillActivityVO seckillingList(Long shopId);

    List<SeckillActivityGoodsVO> willSeckillList(Long shopId);

    void addSaleNum(Order order);

    void decSaleNum(Order order);

    Integer getStock(Long activityGoodsId);

    void payExpireHandler(Order order);

    /**
     * 判断当前时间段有没有指定秒杀活动的商品存在
     *
     * @param serkillId 秒杀活动id
     * @param goodsId   商品id
     * @return
     */
    Boolean verifyBySerkillAndGoods(Long serkillId, Long goodsId);

    /**
     * 判断当前时间段有没有指定秒杀活动商品存在
     *
     * @param serkillGoodsId 秒杀活动商品id
     * @return
     */
    Boolean verifyBySerkillGoods(Long serkillGoodsId);


    /**
     * 创建并设置信号量
     *
     * @param
     */
    void createAndSetSemaphore(SeckillActivityGoods goods);

    /**
     * 根据活动商品获取当前的信号
     *
     * @param goods
     * @return
     */
    RSemaphore getSemaphore(SeckillActivityGoods goods);

    /**
     * 获取信号量，如果获取成功信号号会减少
     *
     * @param activityId
     * @param activityGoodsId
     * @param goodsId
     * @param size
     * @return
     */
    Boolean tryAcquire(Long activityId, Long activityGoodsId, Long goodsId, int size);

    /**
     * 释放（回退）信号量,
     *
     * @param goods
     * @param size
     */
    void release(SeckillActivityGoods goods, int size);

    void release(Long activityId, Long activityGoodsId, Long goodsId, int size);

    /**
     * 获取秒杀信号量的key
     *
     * @param activityId
     * @param activityGoodsId
     * @param goodsId
     * @return
     */
    static String getSemaphoreKey(Long activityId, Long activityGoodsId, Long goodsId) {
        return "seckill:activityId:" + activityId + "activityGoodsId:" + activityGoodsId + "_goodsId:" + goodsId;
    }

    List<SeckillGoodsSku> getSkusById(Long seckillGoodsId);

    SeckillActivityAppVO flashSale(Map<String, Object> params);

    SeckillActivityAppVO startFlashSale(Map<String, Object> params);

    void verifyActiveGoods(Long seckillId);

    public List<SeckillActivityGoodsVO> seckillingGoodsList(Long shopId);
}

